home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
mvssrc.zip
/
GOPHER
< prev
next >
Wrap
Text File
|
1992-04-13
|
6KB
|
188 lines
/*******************************************************************
*
* This member contains a simple TCP/IP server. It waits for
* a tcpip connection request, and then starts a subtask to
* service that request.
*
* This server follows the GOPHER protocols defined by UMN.
* For more information, see the ANONYMOUS FTP site at
* BOOMBOX.MICRO.UMN.EDU.
*
*******************************************************************/
#pragma nomargins
#include "tcpincl" /* All system file includes needed. */
static int sockfd; /*socket for accepting connections*/
static struct sockaddr_in server; /*server address information */
#include "ebdasc" /* ebcdic-->ascii conversion stuff */
#include "mtferror" /* MTF error reporting routines */
int tcpsetup(int port,int qlen)
/***************************************************************/
/*
* This routine sets up the socket connection.
*
* INPUT: port - socket to connect to
* qlen - length of pending request queue len
*
* OUTPUT: TRUE - successfully set up socket
* FALSE - socket setup failed.
*/
/***************************************************************/
{
int x; /* loop counter*/
struct linger l; /* linger for setsockopt */
/* initialize the MTF environment. */
if(mtfichk(tinit("GPHPTSK", MTF_TASKS))!=0) exit(8);
/* open a TCP socket... */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
tcperror("SOCKET - ");
return(0);
};
/* set the linger option on so we wait for data to be sent... */
l.l_onoff = 1;
l.l_linger=100; /* wait 100 seconds before giving up */
if(setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(char *) &l,sizeof(l))<0)
{
tcperror("SETSOCKOPT - ");
}
/* now bind our local address so that the client can send to us */
bzero((char *) &server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
if (bind(sockfd, &server, sizeof(server))<0)
{
tcperror("BIND - ");
return(0);
}
/* now set length of the connection queue... */
if (listen(sockfd,qlen)!=0)
{
tcperror("LISTEN -");
}
return(1);
}
void spawn(int newsockfd)
/********************************************************************/
/*
* This routine starts a subtask, passing control of a socket
* to it. It then waits for the subtask to take the socket and
* then closes the socket.
*
* INPUT: newsockfd - socket descriptor to give to subtask.
*/
/********************************************************************/
{
struct clientid clid;
char mysname[8];
if(getclientid(AF_INET,&clid)<0) tcperror("GETCLIENTID");
clid.domain = AF_INET;
memcpy(mysname,clid.subtaskname,8);
memcpy(clid.subtaskname," ",8);
if(givesocket(newsockfd,&clid) != 0) tcperror("GIVESOCKET");
memcpy(clid.subtaskname,mysname,8);
if(mtfscchk(tsched(MTF_ANY,"receive",newsockfd,clid))!=0) exit(4);
if (closesock(newsockfd)<0) printf("Connection timed out!");
}
int closesock(int newsockfd)
/********************************************************************/
/*
* This routine waits for an exception on the socket. When one
* occurs (by a subtask's "TAKESOCKET"!) we'll close our (the main
* task's) connection to it.
*
* INPUT s pointer to socket descripter.
* OUTPUT rc -1 = connection timed out...
* 0 = an excption occured!
*/
/********************************************************************/
{
int temps;
struct sockaddr clientaddress;
int addrlen;
int maxfdpl;
struct fd_set readmask;
struct fd_set writmask;
struct fd_set exepmask;
int rc;
struct timeval time;
temps = newsockfd;
time.tv_sec = CONNECT_TIME_OUT;
time.tv_usec = 0;
maxfdpl = temps + 1;
FD_ZERO(&readmask);
FD_ZERO(&writmask);
FD_ZERO(&exepmask);
FD_SET(temps, &exepmask);
rc = select(maxfdpl, &readmask, &writmask, &exepmask, &time);
if (rc < 0)
{
tcperror("SELECT - ");
return rc;
}
else
{
if(rc=0) printf("The GIVESOCKET timed out!\n");
if(close(newsockfd)<0) tcperror("CLOSE -");
return rc;
}
}
int main(void)
{
int x; /* loop counter*/
char buffer[255]; /* buffer for input/output*/
int newsockfd; /*new connection socket...*/
struct sockaddr_in client; /*client address information */
struct clientid clid; /*client info for givesocket */
int clientlen; /*new connection socket...*/
/******************************************************************/
/* set up the connection to the socket... */
/******************************************************************/
if(!tcpsetup(SERV_TCP_PORT,TCP_QUEUE_LENGTH))
{
printf("could not set up the tcpip environment!\n");
exit(16);
}
/******************************************************************/
/* Now loop, waiting for a connection request. */
/******************************************************************/
clientlen = sizeof(client);
x = 0;
while(1==1)
{
if((newsockfd=accept(sockfd,&client,&clientlen)) == -1)
{
tcperror("ACCEPT - ");
exit(8);
}
x++;
spawn(newsockfd);
};
/******************************************************************/
/* Wait for all pending tasks to complete (should never */
/* run, since I haven't added PURGE support yet...) */
/* then shut down subtasks. */
/******************************************************************/
if(tsyncro(MTF_ALL)!=0) perror("TSYNCRO");
if(mtfsychk(tsyncro(MTF_ALL))!=0) exit(8);
if(mtftrchk(tterm())!=4) exit(8);
}